#!/usr/bin/env python3
import os
import re
import sys
import time
import subprocess
from datetime import datetime


def PrintUsage():
    print("""用法参考readme.""")


class Parser(object):
    speed_split_flag = 'Term-00, Running '
    
    def __init__(self):
        self.run_seconds = 0
        self.just_start = True
        self.last_tpmtotal = 0

    def format_speed_line(self, line):
        """
        解析tpcc实时速度。
        """
        numbers = re.findall(r'\d+\.\d+|\d+', line)
        tpmavg = float(numbers[0])
        tpmtotal = int(numbers[1])
        tpccres = tpmavg * 0.45
        tpmspeed = tpmtotal - self.last_tpmtotal
        self.last_tpmtotal = tpmtotal
        self.run_seconds += 1
        
        # if just start up
        if tpccres == 0 and self.just_start:
            return f"prepare time:{self.run_seconds}s, prepare tpcc terminals......"
        
        if self.just_start:
            self.just_start = False
            self.run_seconds = 1
        
        return "{0}s:\ttpmC(total={1},  avg={2:.2f},  speed={3})\ttpccRes={4:.2f}".format(
            self.run_seconds, tpmtotal, tpmavg, tpmspeed, tpccres)


def parse_exists_file(file):
    """
    从头到尾解析tpcc输出文件。
    """
    parser = Parser()
    with open(file, 'r') as f:
        content = f.read()
    content = content.replace('\b', '\n').replace(Parser.speed_split_flag, '\n')
    lines = content.splitlines()
    for line in lines:
        if not line.startswith('Average'):
            print(line)
            continue
        format_line = parser.format_speed_line(line)
        print(format_line)


def run_and_parse_output():
    def print_write_flog(_content, _file):
        print(_content)
        _file.write(_content + '\n')
        _file.flush()
    
    # prepare tmp result log dir
    result_dir = 'tpccrecorder_results'
    if not os.access(result_dir, os.F_OK):
        os.system(f'mkdir {result_dir}')
    
    current_time = datetime.now().strftime("%Y-%m-%d_%H_%M_%S")
    origin_log = os.path.join(result_dir, f'tpcc_output_{current_time}.origin.log')
    format_log = os.path.join(result_dir, f'tpcc_output_{current_time}.format.log')
    format_log_file = open(format_log, 'w')

    origin_tpcc_cmd = ' '.join(sys.argv[1:])
    print_write_flog(f"                                            \n"
                     f"TPCC RECORDER INFO:                         \n"
                     f"    origin tpcc command: {origin_tpcc_cmd}  \n"
                     f"    origin log: {origin_log}                \n"
                     f"    format log: {format_log}                \n"
                     f"                                            \n"
                     f"START UP TPCC:                              \n",
                     format_log_file
    )

    # START UP TPCC
    run_tpcc_cmd = '{0} > {1}'.format(origin_tpcc_cmd, origin_log)
    tpcc = subprocess.Popen(run_tpcc_cmd, stdout=subprocess.PIPE, shell=True)
    time.sleep(1)

    # 1.get log first part
    status, output = subprocess.getstatusoutput(f'cat {origin_log}')
    print_write_flog(output, format_log_file)

    # 2.get running log
    parser = Parser()
    while tpcc.poll() is None:
        time.sleep(1)
        status, output = subprocess.getstatusoutput(f'cat {origin_log} | tail -c 400')
        resline = output.split('Term-00, Running ')[-1].replace('\b', '')
        
        if not resline.startswith('Average'):
            continue
        
        format_line = parser.format_speed_line(resline)
        print_write_flog(format_line, format_log_file)
    
    # 3.get end log
    status, output = subprocess.getstatusoutput(f'cat {origin_log} | tail -n 7')
    print_write_flog(output, format_log_file)

    format_log_file.close()


if __name__ == '__main__':
    if len(sys.argv) == 1 or sys.argv[1] in ['-h', '--help', '-?']:
        PrintUsage()
        
    elif sys.argv[1] in ['-f', '--file']:
        parse_exists_file(sys.argv[2])
        
    else:
        run_and_parse_output()
        
        
